#include "NormalPDF.h"
#include <cmath>

NormalPDF::NormalPDF() {
    v = 0;
}

double NormalPDF::evaluate(double x) {
    static const double inv_sqrt_2pi = 0.3989422804014327;
    return inv_sqrt_2pi * std::exp(-0.5 * x * x);
}


double NormalPDF::integral(double a, double b, int nPoints) {
    double h = (b - a) / nPoints;
    double x = a + 0.5 * h;
    double total = 0.0;
    for (int i = 0; i < nPoints; i++) {
        double y = evaluate(x);
        total += y;
        x += h;
    }
    return h * total;
}

/*
 TESTS for NormalPDF
*/

static void testNormalPDF() {
    rng("default");
    NormalPDF nPdf;
    double p = nPdf.integral(-1.96, 1.96,10000);
    ASSERT_APPROX_EQUAL(p, 0.95, 0.1);
}

static void testEvaluate0() {
    rng("default");
    NormalPDF nPdf;
    double p = nPdf.evaluate(-1000000000);
    ASSERT_APPROX_EQUAL(p, 0, 0.1);
    
}

static void testEvaluate1() {
    rng("default");
    NormalPDF nPdf;
    double p1 = nPdf.evaluate(0);
    ASSERT_APPROX_EQUAL(p1, 0.3989, 0.1);
}

static void testEvaluate2() {
    rng("default");
    NormalPDF nPdf;
    double p2 = nPdf.evaluate(10000000000);
    ASSERT_APPROX_EQUAL(p2, 0, 0.1);
}

void testNormalPDFIntergal() {
    TEST(testNormalPDF);
    TEST(testEvaluate0);
    TEST(testEvaluate1);
    TEST(testEvaluate2);
}